﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace AppiSynchro.Library.Helpers
{
    public class VersionHelper
    {
        public static String GetFileVersion(String file)
        {
            return GetFileVersionWin32(file);
        }

        private static String GetFileVersionWin32(String file)
        {
            unsafe
            {
                try
                {
                    int handle = 0;
                    // Figure out how much version info there is:
                    int size =
                          Win32Imports.GetFileVersionInfoSize(file,
                          out handle);

                    if (size == 0) return null;

                    byte[] buffer = new byte[size];

                    if (!Win32Imports.GetFileVersionInfo(file, handle, size, buffer))
                    {
                        Console.WriteLine("Failed to query file version information.");
                        return null;
                    }

                    short* subBlock = null;
                    uint len = 0;
                    // Get the locale info from the version info:
                    if (!Win32Imports.VerQueryValue(buffer, @"\VarFileInfo\Translation", out subBlock, out len))
                    {
                        Console.WriteLine("Failed to query version information.");
                        return null;
                    }

                    string spv = @"\StringFileInfo\" + subBlock[0].ToString("X4") + subBlock[1].ToString("X4") + @"\ProductVersion";

                    byte* pVersion = null;
                    // Get the ProductVersion value for this program:
                    string versionInfo;

                    if (!Win32Imports.VerQueryValue(buffer, spv, out versionInfo, out len))
                    {
                        Console.WriteLine("Failed to query version information.");
                        return null;
                    }

                    return versionInfo;
                }
                catch (Exception e)
                {
                    Console.WriteLine("Caught unexpected exception " + e.Message);
                }

                return null;
            }
        }

    }
    public class Win32Imports
    {
        [DllImport("version.dll")]
        public static extern bool GetFileVersionInfo(string sFileName,
              int handle, int size, byte[] infoBuffer);
        [DllImport("version.dll")]
        public static extern int GetFileVersionInfoSize(string sFileName,
              out int handle);

        // The third parameter - "out string pValue" - is automatically
        // marshaled from ANSI to Unicode:
        [DllImport("version.dll")]
        unsafe public static extern bool VerQueryValue(byte[] pBlock,
              string pSubBlock, out string pValue, out uint len);
        // This VerQueryValue overload is marked with 'unsafe' because 
        // it uses a short*:
        [DllImport("version.dll")]
        unsafe public static extern bool VerQueryValue(byte[] pBlock,
              string pSubBlock, out short* pValue, out uint len);
    }
}
